home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1996 / MacHack 1996.toast / Hacks / Hacks '96 / Talking Telnet / source / main / event.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-06-22  |  28.2 KB  |  1,025 lines  |  [TEXT/CWIE]

  1. /*
  2. *    event.c
  3. *****************************************************************
  4. *    NCSA Telnet for the Macintosh                                *
  5. *                                                                *
  6. *    National Center for Supercomputing Applications                *
  7. *    Software Development Group                                    *
  8. *    152 Computing Applications Building                            *
  9. *    605 E. Springfield Ave.                                        *
  10. *    Champaign, IL  61820                                        *
  11. *                                                                *
  12. *    Copyright (c) 1986-1993,                                    *
  13. *    Board of Trustees of the University of Illinois                *
  14. *****************************************************************
  15. *
  16. *    Main Event loop code for NCSA Telnet for the Macintosh
  17. *
  18. *    Called by:
  19. *        maclook.c
  20. *
  21. *    Revisions:
  22. *    7/92    Telnet2.6:    added 2 support for 2 global structs, put cursors into
  23. *                        an array, cleaned up defines            Scott Bulmahn                        
  24. *
  25. */
  26.  
  27. #ifdef MPW
  28. #pragma segment 4
  29. #endif
  30.  
  31. /*
  32.  *    Files for inclusion.
  33.  */
  34.  
  35.  
  36. #include "VSkeys.h"
  37. #include "wind.h"
  38. #include "event.h"     //kxplate moved to its own file (CCP 2.7)
  39. #include "errors.proto.h"
  40. #include "network.proto.h"
  41. #include "mydnr.proto.h"
  42. #include "bkgr.proto.h"
  43. #include "maclook.proto.h"
  44. #include "InternalEvents.h"
  45. #include "vsdata.h"
  46. #include "vsinterf.proto.h"
  47. #include "menuseg.proto.h"
  48. #include "vrrgmac.proto.h"
  49. #include "tekrgmac.proto.h"
  50. #include "rsinterf.proto.h"
  51. #include "rsmac.proto.h"
  52. #include "event.proto.h"
  53. #include "macros.proto.h"                /* For setmacro proto */
  54. #include "netevent.proto.h"
  55. #include "translate.proto.h"
  56. #include "parse.proto.h"
  57. #include "linemode.proto.h"
  58. #include "Connections.proto.h"
  59. #include "mainseg.proto.h"
  60. #include "speech.proto.h"
  61. #include <Script.h> // for EMACS meta hack
  62. #include <Icons.h> //For Notify User Icon Stuff
  63. extern short        scrn;
  64. extern MenuHandle    myMenus[NMENUS];
  65. extern Boolean        gKeyboardHasControlKey;
  66. extern SysEnvRec    theWorld;        /* BYU 2.4.12 - System Environment record */
  67. extern WindRec        *screens,
  68.                     *ftplog;
  69. extern Cursor        *theCursors[];
  70. extern Boolean         gHaveDragMgr;
  71.  
  72. static gHaveInstalledNotification = 0;
  73. NMRec *nRecPtr;
  74.  
  75. #include "event.proto.h"
  76.  
  77. short updateCursor(short force)
  78. {
  79.     static Point    lastPoint;
  80.     static short    optwasdown;
  81.     short            optDown;
  82.     Point            myPoint;
  83.     KeyMap            allthekeys;            /* Someplace to put the keymap */
  84.  
  85.     if (TelInfo->myfrontwindow) {                    /* BYU 2.4.11 */
  86.         SetPort((GrafPtr) TelInfo->myfrontwindow);    /* BYU 2.4.11 */
  87.     } else {                                /* BYU 2.4.11 */
  88.         SetCursor(theCursors[normcurs]);                /* BYU 2.4.11 */
  89.         return(0);                            /* BYU 2.4.11 */
  90.     }
  91.  
  92.     GetMouse(&myPoint);
  93.  
  94.     GetKeys(allthekeys);
  95.     optDown = ((unsigned char *)allthekeys)[7] &4;
  96.  
  97.     if ( (!force) && EqualPt(myPoint,lastPoint) && (optDown ==optwasdown))
  98.         return(0);
  99.  
  100.     if (force)
  101.         TelInfo->lastCursor=0L;
  102.     if (TelInfo->ginon) {
  103.         if (TelInfo->lastCursor!= theCursors[gincurs]) {
  104.             SetCursor(theCursors[gincurs]);
  105.             TelInfo->lastCursor = theCursors[gincurs];
  106.             }
  107.         return(1);
  108.         }
  109.  
  110.     if (TelInfo->xferon && !optDown) {
  111.         if  (TelInfo->lastCursor!= theCursors[xfercurs]) {
  112.             SetCursor( theCursors[xfercurs]);
  113.             TelInfo->lastCursor = theCursors[xfercurs];
  114.             }
  115.         return(1);
  116.         }
  117.  
  118.     switch (TelInfo->myfronttype) {
  119.         case DEC_WINDOW:
  120.             if (RSmouseintext( TelInfo->myfrontvs, myPoint)) 
  121.             {
  122.             
  123.                 if ((PointInSelection(normalize(myPoint, TelInfo->myfrontvs, FALSE),
  124.                             TelInfo->myfrontvs))&&(gHaveDragMgr)) //for Drag ability
  125.                     
  126.                 {
  127.                     if (TelInfo->lastCursor != theCursors[normcurs]) 
  128.                     {
  129.                         TelInfo->lastCursor  = theCursors[normcurs];
  130.                         SetCursor(theCursors[normcurs]);
  131.                     }
  132.                 }
  133.                 else
  134.                 {
  135.                     if (optDown)                /* Option key is down */
  136.                     {
  137.                         if (TelInfo->lastCursor != theCursors[poscurs]) 
  138.                         {
  139.                             TelInfo->lastCursor  = theCursors[poscurs];
  140.                             SetCursor(theCursors[poscurs]);
  141.                         }
  142.                     } 
  143.                     else 
  144.                     {
  145.                         if (TelInfo->lastCursor != theCursors[textcurs]) 
  146.                         {
  147.                             TelInfo->lastCursor  = theCursors[textcurs];
  148.                             SetCursor(theCursors[textcurs]);
  149.                         }
  150.                     }
  151.                 }
  152.             } 
  153.             else 
  154.             {
  155.                 if (TelInfo->lastCursor != theCursors[normcurs]) 
  156.                 {
  157.                     TelInfo->lastCursor  = theCursors[normcurs];
  158.                     SetCursor(theCursors[normcurs]);
  159.                 }
  160.             }
  161.             break;
  162.         case TEK_WINDOW:
  163.             LocalToGlobal(&myPoint);
  164.             if (PtInRgn(myPoint, TelInfo->myfrontwindow->contRgn)) {        /* BYU LSC */
  165.                 if (TelInfo->lastCursor != theCursors[graphcurs]) {
  166.                     TelInfo->lastCursor  = theCursors[graphcurs];
  167.                     SetCursor(theCursors[graphcurs]);
  168.                     }
  169.             } else {
  170.                 if (TelInfo->lastCursor != theCursors[normcurs]) {
  171.                     TelInfo->lastCursor  = theCursors[normcurs];
  172.                     SetCursor(theCursors[normcurs]);
  173.                     }
  174.             }
  175.             break;
  176.         case NO_WINDOW:
  177.         default:
  178.             if (force) {
  179.                 SetCursor( theCursors[normcurs]);
  180.                 TelInfo->lastCursor= theCursors[normcurs];
  181.                 }
  182.         }
  183.     lastPoint=myPoint;
  184.     optwasdown=optDown;
  185.     return(0);
  186. }
  187.  
  188. void NoWindow( void)
  189. {
  190.         TelInfo->myfrontwindow=0L;
  191.         TelInfo->myfronttype=NO_WINDOW;
  192.         TelInfo->myfrontRgn=0L;
  193.         updateCursor(1);
  194. }
  195.  
  196. /*     The following code was graciously donated by Marc Tamsky.  When are YOU going to donate
  197.     YOUR code, eh?  We know you're reading this.  -- JMB */
  198.  
  199. Boolean CheckPageKeys(short code)                                            /* NCSA: SB */
  200. {                                                                            /* NCSA: SB */
  201.     GrafPtr currFW;     // current front window holder                      // MAT--
  202.     short     ourW;       // virtual screen number holder                     // MAT--kinda
  203.     short     x1, y2, x2, y1; // coordinates from window                      // MAT--pulled from scrollproc
  204.                                                                             /* NCSA: SB */
  205.     currFW = (GrafPtr)FrontWindow();                                        // MAT--
  206.     ourW = RSfindvwind(currFW);                                             // MAT--
  207.                                                                             /* NCSA: SB */    
  208.     switch (code)                                                            /* NCSA: SB */
  209.         {                                                                    /* NCSA: SB */
  210.         case VSPGUP:                                                        /* NCSA: SB */
  211.             RScursblinkoff(ourW);
  212.             VSgetrgn(ourW, &x1, &y1, &x2, &y2);                               // MAT--
  213.             VSscrolback(ourW, y2 - y1); /* scroll a whole windowful */      // MAT--
  214.             return TRUE;                                                       // MAT--
  215.             break;                                                            /* NCSA: SB */                                                            
  216.                                                                             /* NCSA: SB */
  217.         case VSPGDN:                                                           // MAT--121 is a PAGE DOWN.                                                                          
  218.             RScursblinkoff(ourW);                                                                // MAT--in rsmac.c
  219.             VSgetrgn(ourW, &x1, &y1, &x2, &y2);                             // MAT--
  220.             VSscrolforward(ourW, y2 - y1); /* scroll a whole windowful */   // MAT--
  221.             return TRUE;                                                    // MAT--
  222.             break;                                                             /* NCSA: SB */
  223.                                                                               // MAT--
  224.         case VSHOME:                                                        /* NCSA: SB */
  225.             RScursblinkoff(ourW);
  226.             VSscroltop(ourW);                                                /* JMB 2.6 -- Created VSscroltop just for this purpose */
  227.             return TRUE;                                                    /* NCSA: SB */
  228.             break;                                                             // MAT--
  229.                                                                                // MAT--
  230.         case VSEND:                                                            /* NCSA: SB */
  231.             RScursblinkoff(ourW);
  232.             VSgetrgn(ourW, &x1, &y1, &x2, &y2);                             // MAT--
  233.             VSscrolforward(ourW, 32765); /* scroll a whole BUNCH! */        // MAT-- kludge time again.  anyone suggest
  234.             return TRUE;                                                    /* NCSA: SB */
  235.             break;                                                             // MAT--  a better way to hack this part?
  236.         }                                                                   // MAT--
  237.                                                                             /* NCSA: SB */
  238.     return FALSE;            /* NCSA: SB - we didnt handle event, let us know about it */
  239. }                                                                            /* NCSA: SB */
  240.  
  241.  
  242. /*  HandleKeyDown --
  243.         By now, we have already gotten a keypress signal from the event handler, so we
  244.         just need to interpret it.  Get the    raw code and ascii value, and then decide
  245.         what to do with it.    */    
  246.  
  247. void HandleKeyDown(EventRecord theEvent,struct WindRec *tw)
  248. {
  249.     unsigned char ascii, code;
  250.     unsigned char sendch;
  251.     long    menuEquiv;
  252.     short    enterkey = 0;
  253.     Boolean    commanddown, optiondown, controldown,shifted;
  254.     ObscureCursor();
  255.     
  256.     ascii = theEvent.message & charCodeMask;
  257.     code = ((theEvent.message & keyCodeMask) >> 8);
  258.     commanddown = ((theEvent.modifiers & cmdKey) != 0);
  259.     optiondown = ((theEvent.modifiers & optionKey) != 0);
  260.     controldown = ((theEvent.modifiers & controlKey) != 0);
  261.     shifted = ((theEvent.modifiers & shiftKey) != 0);
  262.     if (DebugKeys(commanddown, ascii, tw->vs))
  263.         return;
  264.  
  265.     if ((tw->emacsmeta == 2)&&(optiondown))
  266.         goto emacsHack;  //ha ha hack hack
  267.  
  268.     if ((code == 0x34)&&(ascii == 3)) //fix for PowerBook 540  bad KCHR
  269.         ascii = 13;                 //(map control-c to return)
  270.     else if ((controldown)&&(shifted)&&(ascii == '2'))
  271.         ascii = 0;//fix bad KCHR control-@
  272.     else if ((controldown)&&(shifted)&&(ascii == '6'))
  273.         ascii = 0x1e;//fix bad KCHR control-^
  274.  
  275.     if (commanddown)          
  276.     { 
  277.         if (gApplicationPrefs->CommandKeys)
  278.         {
  279.             //if optioned, retranslate so we can do menu commands
  280.             if (optiondown)
  281.             {
  282.                 short virtualCode = 0;
  283.                 Ptr KCHRPtr;
  284.                 long newStuff;
  285.                 unsigned long state = 0;
  286.                 short modifiersCopy;
  287.                 modifiersCopy = theEvent.modifiers;
  288.                 virtualCode = (short)(code);
  289.                 
  290.                 theEvent.modifiers &= (shiftKey); //turn off option
  291.                 virtualCode |= theEvent.modifiers;  
  292.                 KCHRPtr  = (Ptr)GetScriptManagerVariable(smKCHRCache);
  293.                 newStuff = KeyTranslate(KCHRPtr,virtualCode,&state);
  294.                 newStuff &= 0xFF; //only look at bottom byte
  295.                 ascii = (unsigned char) newStuff;
  296.                 theEvent.modifiers = modifiersCopy; //reset option state
  297.             }
  298.  
  299.             menuEquiv = MenuKey(ascii); //handle menu keys first
  300.             if ((menuEquiv & 0xFFFF0000) != 0) 
  301.             {
  302.                 HandleMenuCommand(menuEquiv,theEvent.modifiers);
  303.                 return;
  304.             }
  305.             if ((TelInfo->numwindows < 1) || (tw->active != CNXN_ACTIVE)) 
  306.                 return;
  307.             //    Check for EMACS meta key.  
  308.             if ((tw->emacsmeta)&&(controldown))
  309.             {        
  310.                 unsigned char temp[2];
  311.                 if (ascii <= 32) //control changed the ascii value
  312.                     ascii |= 0x40; //move back to a non-control
  313.                 if ((shifted)||(ascii == 0x5f)) //so we can get meta -
  314.                 {
  315.                     short virtualCode = 0;
  316.                     Ptr KCHRPtr;
  317.                     long newStuff;
  318.                     unsigned long state = 0;
  319.                     virtualCode = (short)(code);
  320.                     theEvent.modifiers &= (shiftKey); //turn of command
  321.                     virtualCode |= theEvent.modifiers;  
  322.                     KCHRPtr  = (Ptr)GetScriptManagerVariable(smKCHRCache);
  323.                     newStuff = KeyTranslate(KCHRPtr,virtualCode,&state);
  324.                     newStuff &= 0xFF; //only look at bottom byte
  325.                     ascii = (unsigned char) newStuff;
  326.                 }
  327.     emacsHack: //if the option key KCHR is installled, we will get the right ascii value
  328.                 if ((tw->clientflags & PASTE_IN_PROGRESS)&&(tw->pastemethod)) //queue this
  329.                 {
  330.                     tw->kbbuf[tw->kblen++] = ESC;
  331.                     tw->kbbuf[tw->kblen++] = ascii;
  332.                     return;
  333.                 }
  334.                 if (tw->kblen > 0)
  335.                 {
  336.                     netwrite( tw->port,tw->kbbuf,tw->kblen);                                        
  337.                     tw->kblen=0;                                                
  338.                 }
  339.                     
  340.                 temp[0] = ESC;
  341.                 temp[1] = ascii;
  342.                 if (tw->echo && tw->halfdup)         
  343.                     parse(tw,temp,2);    
  344.                 netpush(tw->port);            
  345.                 netwrite(tw->port,temp,2);    
  346.                 return;                                            
  347.             }
  348.             else if (ascii >='0' && ascii <='9' )  //now look for macros
  349.             {
  350.                 sendmacro(tw, ascii-'0');
  351.                 return;
  352.             }
  353.             else if (!((ascii == '`' && gApplicationPrefs->RemapTilde)||(code == BScode)))
  354.                 return;
  355.         }
  356.         else //no command key menus
  357.         {
  358.             if ((TelInfo->numwindows < 1) || (tw->active != CNXN_ACTIVE)) 
  359.                 return;
  360.             else if (!gKeyboardHasControlKey) //map command to control
  361.             {
  362.                 ascii &= 0x1f;
  363.                 commanddown = FALSE;
  364.             }
  365.             else
  366.                 return;
  367.         }
  368.     } else if ((TelInfo->numwindows < 1) || (tw->active != CNXN_ACTIVE)) 
  369.         return;
  370.  
  371.  
  372.     if (((ascii == '@') || (ascii == 32))&& controldown) //this, along with the fixed KCHR that mapps a Cntl-@ to
  373.         ascii = NULL;                 //a @, takes care of Apple not posting NULL key values
  374.     
  375.     //    map '`' to ESC if needed
  376.     if (ascii == '`' && gApplicationPrefs->RemapTilde && !(commanddown))
  377.         ascii = ESC;
  378.     
  379.     if (code == BScode) //handle mapping BS to DEL, flipping on option
  380.     {
  381.         if (tw->bsdel)
  382.             if ((optiondown)||(commanddown))
  383.                 ascii = BS;
  384.             else
  385.                 ascii = DEL;
  386.         else
  387.             if ((optiondown)||(commanddown))
  388.                 ascii = DEL;
  389.             else
  390.                 ascii = BS;
  391.     }
  392.         
  393.     if (!tw->enabled) //if we are suspended, and we have negotiated restart_any 
  394.     {                //with the host, then enable the screen on anything but an XOFF.  We will
  395.                     //eat the XON later if that is what this is. (RFC 1372 --CCP 2.7)
  396.         if ((tw->restart_any_flow)&&(ascii != tw->TELstop))
  397.             tw->enabled = 1;
  398.     }
  399.  
  400.     /* Remap PgUp,PgDown,Home,End if the user wants it that way */
  401.     if ((tw->pgupdwn && (code >= KPlowest))||(!tw->vtemulation)) //do page up/down on vt100
  402.         if (CheckPageKeys(code)) return;        
  403.  
  404.     if (code >= KPlowest)         /* BYU - Handle Keypad */
  405.     {
  406.         if (theWorld.keyBoardType == envStandADBKbd)    //standard MacII keyboard has keypad +,- 
  407.         {                                                // codes switched    
  408.             if (code == 0x45)                                    
  409.                 code = 0x4e;
  410.             else if (code == 0x4e)
  411.                 code = 0x45;
  412.         }
  413.  
  414.         if ((tw->vtemulation)||(code >= 0x7B)||(code <= 0x60)) //fkeys dont work in vt100
  415.         {
  416.             if ((!tw->keypadmap)||(code == 0x4c)||(code > 0x51)||(code < 0x43)) //dont remap operators
  417.             {
  418.                 if ((tw->clientflags & PASTE_IN_PROGRESS)&&(tw->pastemethod)) //queue this
  419.                 {
  420.                     tw->kbbuf[tw->kblen++] = 0;
  421.                     tw->kbbuf[tw->kblen++] = kpxlate[shifted][code - KPlowest];
  422.                     return;
  423.                 }
  424.     
  425.                 if (tw->kblen > 0)
  426.                 {
  427.                     netwrite( tw->port,tw->kbbuf,tw->kblen);                                        
  428.                     tw->kblen=0;                                                
  429.                 }
  430.     
  431.                 ascii = kpxlate[shifted][code - KPlowest];
  432.                 // Should we check here for ascii being zero?
  433.                 VSkbsend(tw->vs, (unsigned char) ascii, tw->echo);
  434.                 return;
  435.             }
  436.         }
  437.         else // we dont handle function keys in vt100
  438.             return;
  439.     }
  440.  
  441.     //    Handle whatever mapping is needed.
  442.     mac_nat(&ascii, tw->national); /* LU/PM: Convert char from mac to nat */
  443.     
  444.     if ((tw->clientflags & PASTE_IN_PROGRESS)&&(tw->pastemethod)) //queue this
  445.     {
  446.         tw->kbbuf[tw->kblen++] = ascii;
  447.         return;
  448.     }
  449.  
  450.     if (tw->lmode)    // Some form of linemode is active; we dont touch it after them
  451.     {
  452.         process_key(ascii,tw);
  453.         return;
  454.     }
  455.     
  456.     
  457.     // BSD-like mapping.... if we don't want this, set chars to zero and it wont work
  458.     //CCP 2.7: this is now AFTER the linemode stuff, so that linemode can handle it differently 
  459.     if (ascii == tw->TELstop)
  460.     {
  461.         if (tw->allow_flow) //remote flow control can turn this off
  462.         {
  463.             tw->enabled = 0;
  464.             return;
  465.         }
  466.     }
  467.  
  468.     if (ascii == tw->TELgo) 
  469.     {
  470.         if (tw->allow_flow) //remote flow control can turn this off
  471.         {
  472.             tw->enabled = 1;
  473.             return;
  474.         }
  475.     }        
  476.     if (ascii == tw->TELip)  
  477.     {
  478.         char *tellUser = "\n\r[Interrupt Process]\n\r";
  479.         parse(tw,(unsigned char *)tellUser,23);
  480.         netpush(tw->port);
  481.         netwrite(tw->port, "\377\364",2);            //IAC IP 
  482.         netpush(tw->port);
  483.         netwrite(tw->port, "\377\375\006",3);        // send Do TM 
  484.         tw->timing = 1;                            // set emulate to TMwait 
  485.         return;
  486.     }
  487.     
  488.  
  489.     if (tw->echo && !tw->halfdup)    // Handle klude-linemode
  490.     {
  491.         if (ascii>31 && ascii <127 && code < KPlowest)    
  492.         {
  493.             if (tw->kblen < (MAXKB -1))     /* Add to buffer if not full */
  494.                 tw->kbbuf[tw->kblen++] = ascii;
  495.             else 
  496.             {            /* if full send buffer */            
  497.                 netwrite( tw->port, tw->kbbuf,tw->kblen);    
  498.                 tw->kbbuf[0] = ascii;
  499.                 tw->kblen=1;
  500.             }
  501.  
  502.             sendch=ascii;
  503.             parse(tw, &sendch, 1);
  504.             return;                                /* OK, were set...*/
  505.         
  506.         } //end if printable key 
  507.         else 
  508.         {
  509.             if ( code == BScode ) 
  510.             {
  511.                 if (tw->kblen>0) 
  512.                 {
  513.                     tw->kblen--;
  514.                     parse(tw,(unsigned char *) "\010 \010",3);    /* BYU LSC */
  515.                 }
  516.                 return;
  517.             }
  518.             else if (ascii == KILLCHAR) 
  519.             {
  520.                 while (tw->kblen >0) 
  521.                 {
  522.                     parse(tw,(unsigned char *) "\010 \010",3);    /* BYU LSC */
  523.                     tw->kblen--;
  524.                 }
  525.                 return;
  526.             }
  527.             else if (code <KPlowest) 
  528.             {
  529.                 netwrite( tw->port, tw->kbbuf,tw->kblen);    /* if full send buffer */
  530.                 tw->kblen=0;
  531.                 if (ascii !=CR) 
  532.                 {
  533.                     sendch='@'+ascii;
  534.                     parse(tw,(unsigned char *) "^",1);    /* BYU LSC */
  535.                     parse(tw, &sendch, 1);
  536.                 }
  537.             }
  538.         }//end else non-printable key
  539.     }//end if klude-linemode
  540.             
  541.  
  542.     if (ascii == '\015') //CR
  543.     {
  544.         //    If crmap is on, send CR-NULL instead of CR-LF.
  545.         netpush(tw->port);                    
  546.         if (tw->crmap) 
  547.             netwrite(tw->port,"\015\0",2);
  548.         else
  549.             netwrite(tw->port,"\015\012",2); //UNIVAC fix
  550.         if (tw->echo) 
  551.             parse(tw,(unsigned char *) "\012\015",2);    /* BYU LSC */
  552.         return;
  553.     }
  554.  
  555.     if (tw->echo && tw->halfdup) 
  556.         parse(tw, &ascii, 1);
  557.         
  558.     if (ascii != 255) 
  559.         netwrite(tw->port,&ascii,1);
  560.     else
  561.         netwrite(tw->port, "\377\377", 2);
  562.         
  563. }
  564.  
  565. void    HandleMouseDown(EventRecord myEvent)
  566. {
  567.     GrafPtr    whichWindow;
  568.     short    code, myRGMnum;
  569.     short     growErr, i;
  570.     code = FindWindow(myEvent.where, &whichWindow);
  571.     
  572.     switch (code) {
  573.         case inMenuBar:
  574.             if (myEvent.modifiers & optionKey)
  575.             {
  576.                 switchToOptionMenus(TRUE);
  577.                 HandleMenuCommand(MenuSelect(myEvent.where),myEvent.modifiers);    
  578.                 switchToOptionMenus(FALSE);
  579.             }
  580.             else if (myEvent.modifiers & shiftKey)
  581.             {
  582.                 switchToShiftMenus(TRUE);
  583.                 HandleMenuCommand(MenuSelect(myEvent.where),myEvent.modifiers);            
  584.                 switchToShiftMenus(FALSE);
  585.             }
  586.             else
  587.                 HandleMenuCommand(MenuSelect(myEvent.where),myEvent.modifiers);            
  588.             break;
  589.         case inSysWindow:
  590.             SystemClick(&myEvent, whichWindow);
  591.             break;
  592.         case inGoAway:
  593.             if (TrackGoAway( whichWindow, myEvent.where))
  594.                 CloseAWindow((WindowPtr)whichWindow);
  595.             break;
  596.  
  597.         case inDrag:
  598.             if ((whichWindow != FrontWindow()) &&
  599.                     (!(myEvent.modifiers & cmdKey)) &&
  600.                     (!(myEvent.modifiers & optionKey))) {
  601.                 SelectWindow(whichWindow);
  602.                 }
  603.             DragWindow(whichWindow, myEvent.where, &TelInfo->dragRect);
  604.             break;
  605.  
  606.         case inZoomIn:
  607.         case inZoomOut:
  608.             if (TrackBox( whichWindow, myEvent.where, code))
  609.                 RSzoom( whichWindow, code, myEvent.modifiers & shiftKey);
  610.             break;
  611.     
  612.     /* NCSA: SB - Telnet now allows you to grow the TEK window, finally.        */
  613.     /* NCSA: SB - So check to see if the click was in a TEK window                */
  614.     
  615.         case inGrow:
  616.             growErr = RSsize( whichWindow, (long *) &myEvent.where, myEvent.modifiers);
  617.             switch(growErr) {
  618.             case (-4):         /*bad mem problems, kill window, signal user */                
  619.                 OutOfMemory(-4);
  620.                 if ((i = WindowPtr2ScreenIndex(whichWindow)) >= 0) 
  621.                 {
  622.                     netclose(screens[i].port);
  623.                     removeport(&screens[i]);
  624.                 }
  625.                 break;
  626.             case (-2):        /* no resize due to memory error, signal user */
  627.                 OutOfMemory(-2);
  628.                 break;
  629.             default:         /* ok resize, or window not found */
  630.                 break;
  631.             }
  632.             myRGMnum = RGfindbywind(whichWindow);            /* NCSA: SB - is it a TEK window click? */
  633.             if (myRGMnum  != -1)            /* NCSA: SB - Anyone want to play some BOLO? */
  634.                 {                                            /* NCSA: SB */
  635.                 RGMgrowme((short)myRGMnum, whichWindow,(long *) &myEvent.where,myEvent.modifiers);    /* NCSA: TG */
  636.                 }                                            /* NCSA: SB */
  637.         break;
  638.         
  639.         case inContent:
  640.             if (whichWindow != FrontWindow()) {
  641.                 SelectWindow(whichWindow);
  642.                 }
  643.             else
  644.                 if (RSclick(whichWindow, myEvent) <0) {
  645.                     SetPort(whichWindow);
  646.                     GlobalToLocal(&myEvent.where);
  647.                     RGmousedown(whichWindow, &myEvent.where );
  648.                     }
  649.             break;
  650.         
  651.         default:
  652.             break;
  653.     }
  654. }
  655.  
  656. #pragma profile off
  657. void    DoEvents( void)
  658. {
  659.     Boolean        gotOne;            /* Did we get an event */
  660.     short        vs;
  661.     EventRecord    myEvent;
  662.     
  663.     gotOne = WaitNextEvent(everyEvent, &myEvent, gApplicationPrefs->TimeSlice, 0L);
  664.  
  665. #ifdef    SPEECH
  666.     if (gDoneSpeaking) {
  667.         StopSpeaking();
  668.     }
  669. #endif    SPEECH
  670.  
  671.     if (gotOne) 
  672.     {
  673.  
  674. /* BYU 2.4.11 - Turn the cursor off when the human makes the slightest move. */
  675.         if (gApplicationPrefs->BlinkCursor) 
  676.         {                                
  677.             if ( (vs=RSfindvwind(FrontWindow())) >= 0)    
  678.                 if (vs == screens[scrn].vs)                
  679.                     if (!(myEvent.modifiers & cmdKey) &&    
  680.                         ((myEvent.what == keyDown) || (myEvent.what == autoKey)))
  681.                         RScursblinkon(vs);                
  682.                     else                                
  683.                         RScursblinkoff(vs);                
  684.         }
  685.         HandleEvent(&myEvent);
  686.     }
  687.     else if (gApplicationPrefs->BlinkCursor && !TelInfo->suspended) 
  688.     {    /* BYU 2.4.11 */
  689.         if ( (vs=RSfindvwind(FrontWindow())) >= 0)        /* BYU 2.4.11 */
  690.             if (vs == screens[scrn].vs)                    /* BYU 2.4.11 */
  691.                 RScursblink(vs);                        /* BYU 2.4.11 */
  692.     }                                                    /* BYU 2.4.11 */
  693.     updateCursor(0);
  694. }                        
  695.  
  696. static long currentScript, defaultKCHR, mungeCount;
  697. static Boolean haveChangedKCHR;
  698. //called at startup to figure out the default roman KCHR and the active script
  699. void scriptKbdInit(void)
  700. {
  701.     currentScript = GetScriptManagerVariable(smKeyScript);//get active script
  702.     defaultKCHR = GetScriptVariable(smRoman, smScriptKeys); //get the smRoman default KCHR
  703.     mungeCount = GetScriptManagerVariable(smMunged); //Get the mungeCount
  704.     haveChangedKCHR = FALSE;
  705. }
  706.  
  707. void SetDefaultKCHR(void)
  708. {
  709.     if (haveChangedKCHR)
  710.     {
  711.         SetScriptVariable(smRoman,smScriptKeys,defaultKCHR);
  712.         haveChangedKCHR = FALSE;
  713.         KeyScript(smRoman);    
  714.     }
  715. }
  716. void CheckDefaultScriptSettings(void)
  717. {
  718.     long tempLong;
  719.     tempLong = GetScriptManagerVariable(smMunged);
  720.     if (tempLong > mungeCount)
  721.     {
  722.         currentScript = GetScriptManagerVariable(smKeyScript);//get the new active script
  723.         if ((currentScript != smRoman)&&(haveChangedKCHR)) //roman has been switched out and we need to fix it
  724.         {    
  725.             SetScriptVariable(smRoman,smScriptKeys,defaultKCHR);
  726.             currentScript = GetScriptManagerVariable(smKeyScript);//get the new active script
  727.             haveChangedKCHR = FALSE; //we dont mess with non-roman scripts    
  728.         }
  729.         mungeCount = tempLong;  //update the mungeCount
  730.     }
  731. }
  732.  
  733.  
  734. void HandleEvent(EventRecord *myEvent) //CCP split this from DoEvents so we can call this from
  735. {                                        //other places
  736.     short i,vs;
  737.     
  738.     switch(myEvent->what) {
  739.     case mouseDown:
  740.         HandleMouseDown(*myEvent);
  741.         break;
  742.  
  743.     case updateEvt:
  744.         switch(((WindowPeek)myEvent->message)->windowKind) {
  745.             case WIN_CONSOLE:
  746.             case WIN_LOG:
  747.             case WIN_CNXN:
  748.                 if (RSupdate((GrafPtr) myEvent->message))
  749.                     putln("Ack, problem in update!");
  750.                 break;
  751.             
  752.             case WIN_ICRG:
  753.                 if (MacRGupdate((WindowPtr) myEvent->message))
  754.                     putln("Ack, problem in update!");
  755.                 break;
  756.                 
  757.             case WIN_TEK:
  758.                 if (RGupdate((GrafPtr) myEvent->message) ==0) 
  759.                     TekDisable(RGgetVG((GrafPtr) myEvent->message));
  760.                 else
  761.                     putln("Ack, problem in update!");
  762.                 break;
  763.             
  764.             default:
  765.                 putln("Bad windowkind!");
  766.                 break;
  767.             }            
  768.         break;
  769.  
  770.     case keyDown:
  771.     case autoKey:
  772.         HandleKeyDown(*myEvent, &screens[scrn]);        /* All key events are processed through here */
  773.         break;
  774.  
  775.     case diskEvt:            /* check to see if disk needs to be initialized */
  776.         myEvent->where.h = 100;
  777.         myEvent->where.v = 120;
  778.         if (noErr != (( myEvent->message >> 16 ) & 0xffff )) {    /* check hi word */
  779.             DILoad();
  780.             DIBadMount( myEvent->where, myEvent->message);    /* BYU LSC */
  781.             DIUnload();
  782.         }
  783.         break;
  784.  
  785.     case activateEvt:
  786.         if ((myEvent->modifiers & activeFlag)==1)  //its an activate event
  787.         {
  788.             i=WindowPtr2ScreenIndex((GrafPtr) myEvent->message);    // We need to know who 
  789.             CheckDefaultScriptSettings(); //see if someone has changed the script
  790.             
  791.             //this next bit takes care of setting the KCHR based on the EMACS hack pref
  792.             if ((currentScript == smRoman)&&(screens[i].emacsmeta == 2))
  793.             {
  794.                 if (!haveChangedKCHR) //if we haven't already done this
  795.                 {
  796.                     SetScriptVariable(currentScript,smScriptKeys,502); //set the KCHR for EMACS
  797.                     KeyScript(smRoman);    //Make it active
  798.                     haveChangedKCHR = TRUE;
  799.                 }
  800.             }
  801.             else if (haveChangedKCHR) //new active window doesnt want EMACS hack
  802.             {
  803.                 SetScriptVariable(currentScript,smScriptKeys,defaultKCHR); 
  804.                 KeyScript(smRoman);    
  805.                 haveChangedKCHR = FALSE;
  806.             }
  807.             AdjustMenus();
  808.             DrawMenuBar();
  809.             i=WindowPtr2ScreenIndex((GrafPtr) myEvent->message);    /* We need to know who */
  810.             if (i>=0) 
  811.             {
  812.                 if ((screens[i].curgraph>-1) && (!(myEvent->modifiers & optionKey)))
  813.                     detachGraphics(screens[i].curgraph);
  814.                 changeport(scrn,i);
  815.                 scrn=i;
  816.             }
  817.             if ((i=RSfindvwind((GrafPtr) myEvent->message))>=0) 
  818.             {
  819.                 if (RSTextSelected(i)) 
  820.                 {                    
  821.                     EnableItem(myMenus[Fil],FLprint);        
  822.                     EnableItem(myMenus[Edit],EDcopy);    
  823.                     EnableItem(myMenus[Edit],EDcopyt);
  824.                 } 
  825.                 else 
  826.                 {                                
  827.                     DisableItem(myMenus[Fil],FLprint);    
  828.                     DisableItem(myMenus[Edit],EDcopy);        
  829.                     DisableItem(myMenus[Edit],EDcopyt);        
  830.                 }
  831. #ifdef    SPEECH
  832.                 AdjustSpeechMenu(RSTextSelected(i));
  833. #endif    /* SPEECH */                                        
  834.                 RSactivate(i);
  835.                 TelInfo->myfrontwindow=(WindowPeek) myEvent->message;
  836.                 TelInfo->myfronttype=DEC_WINDOW;
  837.                 TelInfo->myfrontvs = i;
  838.                 TelInfo->myfrontRgn =0L;
  839.                 updateCursor(1);
  840.             } 
  841.             else 
  842.             {                    
  843.                 TelInfo->myfrontwindow=(WindowPeek) myEvent->message;
  844.                 TelInfo->myfronttype=TEK_WINDOW;
  845.                 TelInfo->myfrontRgn =0L;
  846.                 updateCursor(1);
  847.                 if ( (i = RGgetdnum((GrafPtr) myEvent->message)) >-1) 
  848.                 {
  849.                     if (( i = RGgetVS( i)) >-1) 
  850.                     {
  851.                         EnableItem(myMenus[Fil],FLprint);    // enable printing 
  852.                         EnableItem(myMenus[Edit],EDcopy);    // - enable copying 
  853.                         DisableItem(myMenus[Edit],EDcopyt);    
  854.                         i = findbyVS( i);
  855.                         changeport(scrn,i);
  856.                         scrn=i;
  857.                     }
  858.                 }
  859.             }
  860.         } 
  861.         else //its a disable event
  862.         {
  863.             short i;
  864.             AdjustMenus();
  865.             DrawMenuBar();
  866.             if ((i=RSfindvwind((GrafPtr) myEvent->message))>=0)
  867.                 RSdeactivate(i);
  868.             NoWindow();
  869.         }
  870.         break;
  871.     case osEvt:
  872.         switch(( myEvent->message >>24) &0xff) {    
  873.             case switchEvt:
  874.                 if (myEvent->message & 0x20)
  875.                     /*Convert clipboard here if necc. (it is not)*/;
  876.  
  877.                 if (myEvent->message & 0x1) {        /* Resume Event */
  878.                     GrafPtr window;
  879.  
  880.                     TelInfo->suspended = FALSE;                /* We are no longer in suspension */
  881.                     if (gHaveInstalledNotification)
  882.                     {
  883.                         NMRemove(nRecPtr);
  884.                         DisposeHandle(nRecPtr->nmIcon);
  885.                         gHaveInstalledNotification = FALSE;
  886.                     }
  887.                     DisableItem( myMenus[Edit],EDcut);
  888.                     DisableItem( myMenus[Edit],EDundo);
  889.                     DisableItem( myMenus[Edit],EDclear);
  890.  
  891.                     window = FrontWindow();            /* Who's on first */
  892.                     if ( (vs=RSfindvwind(window)) >= 0) 
  893.                     {
  894.                         CheckDefaultScriptSettings();//update script settings
  895.                         if ((currentScript == smRoman)&&(haveChangedKCHR)) // set it back
  896.                         {
  897.                             SetScriptVariable(currentScript,smScriptKeys,502); //set the KCHR for EMACS
  898.                             KeyScript(smRoman);    //Make it active
  899.                         }
  900.                         RSactivate(vs);
  901.                         TelInfo->myfrontwindow = (WindowPeek) window;
  902.                         TelInfo->myfronttype=DEC_WINDOW;
  903.                         TelInfo->myfrontvs = vs;
  904.                         TelInfo->myfrontRgn =0L;
  905.                         updateCursor(1);
  906.                     } else if ( (long)window != 0L) {
  907.                         myEvent->message = (long) window;
  908.                         myEvent->modifiers |= activeFlag;
  909.                         myEvent->what = activateEvt;
  910.                         myEvent->when = TickCount();
  911.                         SystemEvent( myEvent);
  912.                         }
  913.                     }
  914.                 else {                                /* Suspend Event */
  915.                     GrafPtr window;
  916.                     CheckDefaultScriptSettings();//update script settings
  917.                     if ((currentScript == smRoman)&&(haveChangedKCHR)) //switch out to default KCHR when while suspended
  918.                     {
  919.                         SetScriptVariable(currentScript,smScriptKeys,defaultKCHR); 
  920.                         KeyScript(smRoman);    
  921.                     }
  922.                     TelInfo->suspended=TRUE;                    /* We be in waitin' */
  923.                     EnableItem( myMenus[Edit],EDcut);
  924.                     EnableItem( myMenus[Edit],EDundo);
  925.                     EnableItem( myMenus[Edit],EDclear);
  926.  
  927.                     window = FrontWindow();            /* Who's on first */
  928.                     if ((window = FrontWindow()) != nil) {
  929.                         if ( (vs=RSfindvwind(window)) >= 0)
  930.                             RSdeactivate(vs);
  931.                         else if ( (long)window != 0L) {
  932.                             myEvent->message = (long) window;
  933.                             myEvent->modifiers &= (~activeFlag);
  934.                             myEvent->what = activateEvt;
  935.                             myEvent->when = TickCount();
  936.                             SystemEvent( myEvent);
  937.                             }
  938.                         }
  939.                     NoWindow();
  940.                     }
  941.                 break;            /* switch of myEvent->message >>24 */
  942.             default:
  943.                 break;
  944.             }
  945.         break;
  946.     case kHighLevelEvent:
  947.         (void) AEProcessAppleEvent(myEvent);
  948.         break;            
  949.     }
  950.  
  951. }
  952. //#pragma profile on
  953.  
  954. void    CloseAWindow(WindowPtr    theWindow)
  955. {
  956.     short    i;
  957.     long junk;
  958.     
  959.     switch(((WindowPeek)theWindow)->windowKind) {
  960.         case WIN_CONSOLE:
  961. //            Debugger();                // Can't close the console window
  962.             break;
  963.                     
  964.         case WIN_LOG:
  965.             if (theWindow == ftplog->wind) {
  966.                 CheckItem(myMenus[Fil],FLlog,FALSE);
  967.                 TelInfo->ftplogon = FALSE;
  968.                 RShide(ftplog->vs);
  969.             }
  970.             break;
  971.                     
  972.         case WIN_CNXN:
  973.             if ((i = WindowPtr2ScreenIndex(theWindow)) >= 0) 
  974.             {
  975.                 if ( screens[i].active == CNXN_ISCORPSE)
  976.                     destroyport(i);
  977.                 else 
  978.                 {
  979.                     if ( !ReallyClose( i) ) break;
  980.                     netclose(screens[i].port);
  981.                     removeport(&screens[i]);
  982.                 }
  983.             }
  984.             break;
  985.         
  986.         case WIN_ICRG:
  987.             MacRGdestroy(MacRGfindwind(theWindow));
  988.             MaxMem(&junk);
  989.             break;
  990.             
  991.         case WIN_TEK:
  992.             destroyGraphics(RGgetVG(theWindow));
  993.             MaxMem(&junk);
  994.             break;
  995.         
  996.         default:
  997.             DebugStr("\pBad windowkind!");
  998.             break;
  999.         }            
  1000.  
  1001.         NoWindow();
  1002. }
  1003.  
  1004.  
  1005. void NotifyUser (void)
  1006. {
  1007.     OSErr err = noErr;
  1008.  
  1009.     if ((!TelInfo->suspended)||(!gApplicationPrefs->NotifyUser)||gHaveInstalledNotification)
  1010.         return;
  1011.     
  1012.     nRecPtr = (NMRecPtr) myNewPtr(sizeof(NMRec)); 
  1013.     if (nRecPtr == NULL)
  1014.         return;
  1015.     nRecPtr->qType = nmType;
  1016.     nRecPtr->nmMark = 1;
  1017.     err = GetIconSuite(&(nRecPtr->nmIcon), kNCSAIconFamilyId, svAllSmallData);
  1018.     if (err != noErr) nRecPtr->nmIcon = nil;
  1019.     nRecPtr->nmSound = nil;
  1020.     nRecPtr->nmStr = nil;
  1021.     nRecPtr->nmResp = nil;
  1022.     NMInstall(nRecPtr);
  1023.     gHaveInstalledNotification = TRUE;
  1024. }
  1025.